package my.design.strategy;

/**
 * @author zp
 * @version 1.0
 * @description: 策略选择聚合类
 *
 * 策略模式简介
 * 策略模式：策略模式是一种行为型模式，它将对象和行为分开，将行为定义为 一个行为接口 和 具体行为的实现。
 *      策略模式最大的特点是行为的变化，行为之间可以相互替换。每个if判断都可以理解为就是一个策略。
 *      本模式使得算法可独立于使用它的用户而变化
 *
 * 策略模式包含如下角色：
 * Strategy: 抽象策略类：策略是一个接口，该接口定义若干个算法标识，即定义了若干个抽象方法（如下图的algorithm()）
 * Context: 环境类 /上下文类：
 * 1、上下文是依赖于接口的类（是面向策略设计的类，如下图Context类），
 *      即上下文包含用策略(接口)声明的变量（如下图的strategy成员变量）。
 * 2、上下文提供一个方法（如下图Context类中的的lookAlgorithm()方法），
 *      持有一个策略类的引用，最终给客户端调用。该方法委托策略变量调用具体策略所实现的策略接口中的方法
 *      （实现接口的类重写策略(接口）中的方法，来完成具体功能）
 * 3、ConcreteStrategy: 具体策略类：具体策略是实现策略接口的类（如下图的ConcreteStrategyA类和ConcreteStrategyB类）。
 *      具体策略实现策略接口所定义的抽象方法，即给出算法标识的具体方法。（说白了就是重写策略类的方法！）
 * 策略模式优缺点
 * 1）优点
 *  1、策略模式提供了对“开闭原则”的完美支持，用户可以在不 修改原有系统的基础上选择算法或行为，也可以灵活地增加 新的算法或行为。
 *  2、策略模式提供了管理相关的算法族的办法。
 *  3、策略模式提供了可以替换继承关系的办法。
 *  4、使用策略模式可以避免使用多重条件转移语句。
 *
 * 2）缺点
 *  1、客户端必须知道所有的策略类，并自行决定使用哪一个策略类。
 *  2、策略模式将造成产生很多策略类，可以通过使用享元模式在一 定程度上减少对象的数量。
 *
 * 策略模式适用场景
 * 在以下情况下可以使用策略模式：
 * 1、如果在一个系统里面有许多类，它们之间的区别仅在于它们 的行为，那么使用策略模式可以动态地让一个对象在许多行 为中选择一种行为。
 * 2、一个系统需要动态地在几种算法中选择一种。
 * 3、如果一个对象有很多的行为，如果不用恰当的模式，这些行 为就只好使用多重的条件选择语句来实现。
 * 4、不希望客户端知道复杂的、与算法相关的数据结构，在具体 策略类中封装算法和相关的数据结构，提高算法的保密性与 安全性。
 * 适合的场景有：
 * 1、电商网站支付方式，一般分为银联、微信、支付宝，可以采用策略模式
 * 2、电商网站活动方式，一般分为满减送、限时折扣、包邮活动，拼团等可以采用策略模式
 * @date 2022/11/1 18:54
 */
public class MemberContext {
    // 用户折扣策略接口
    private final MemberStrategy memberStrategy;

    // 注入构造方法
    public MemberContext(MemberStrategy memberStrategy) {
        this.memberStrategy = memberStrategy;
    }

    // 计算价格
    public double qoutePrice(double goodsPrice, int n){
        // 通过接口变量调用对应的具体策略
        return memberStrategy.calcPrice(goodsPrice, n);
    }
}
